Using the Repository-Mode
With the help of Repositories most of the file accesses could be redirected to an self-defined virtual file system. This allows you to manage all project files and their related files in a database. The implementation of such strategy is described in the following setps. An Overview of the use and functionality of the Repository could be found in namespace combit.Reporting.Repository. Following will be demonstrated how the Repository can be used in List & Label. The supplied programming samples for ASP.NET and WinForms show the usage in detail.
Tip
In the following, code sections are shown which have been reduced to a minimum due to their clarity. Any auxiliary functions shown, but can be viewed in full in the supplied samples, since the following description is based on the implementation of the IRepository interface using an SQLite database and its subsequent use in practice in detail in the examples.
Step 1: Definition of the data retention
The managing of the files in List & Label like project files for the designer, P-files for printer settings, table of contents, drawings, shapefiles etc. are normally controlled by the file system of the operating system. Thus List & Label works on the basis of file names and its paths.
As soon as you decide to use the Repository, you need to deal with that question and find an suitable "storage", because of List & Label does no longer work with file paths rather only with so called Repository-IDs. With the help of these IDs the requested elements could be asked and used. Numerous applications use for their data storage something like databases where SQL databases is often chosen. That is the reason why we will use for simple demonstration an SQLite database. And the namespace System.Data.SQLite from the .NET Framework is used for:
public class SQLiteFileRepository
{
private readonly IDbConnection _db;
public SQLiteFileRepository(string databasePath)
{
bool needsDatabaseInit = !File.Exists(databasePath);
_db = new SQLiteConnection("Data Source=" + databasePath);
_db.Open();
if (needsDatabaseInit)
DropAndCreateTables();
}
private void DropAndCreateTables()
{
_db.CreateCommand(@"
DROP TABLE IF EXISTS RepoItems;
CREATE TABLE IF NOT EXISTS RepoItems (
ItemID TEXT,
Type TEXT,
Descriptor TEXT,
TimestampUTC INT,
FileContent BLOB
);").ExecuteNonQuery();
}
}
Public Class SQLiteFileRepository
Private ReadOnly _db As IDbConnection
Public Sub New(databasePath As String)
Dim needsDatabaseInit As Boolean = Not File.Exists(databasePath)
_db = New SQLiteConnection(Convert.ToString("Data Source=") & databasePath)
_db.Open()
If needsDatabaseInit Then
DropAndCreateTables()
End If
End Sub
Private Sub DropAndCreateTables()
_db.CreateCommand("DROP TABLE IF EXISTS RepoItems; CREATE TABLE IF NOT EXISTS RepoItems (ItemID TEXT, Type TEXT, Descriptor TEXT, TimestampUTC INT, FileContent BLOB);").ExecuteNonQuery()
End Sub
End Class
Step 2: Necessary implementation of the interface IRepository
Now the implementation of the interface IRepository need to be done, so you can react individual on the requests of List & Label:
public class SQLiteFileRepository : IRepository
{
public bool ContainsItem(string itemID)
{
// ...
}
public void CreateOrUpdateItem(RepositoryItem item, string userImportData, Stream sourceStream)
{
// ...
}
public void DeleteItem(string itemID)
{
// ...
}
public IEnumerable<RepositoryItem> GetAllItems()
{
// ...
}
public RepositoryItem GetItem(string itemID)
{
// ...
}
public void LoadItem(string itemID, Stream destinationStream, CancellationToken cancelToken)
{
// ...
}
public bool LockItem(string id)
{
// ...
}
public void UnlockItem(string id)
{
// ...
}
}
Public Class SQLiteFileRepository Implements IRepository
Public Function ContainsItem(itemID As String) As Boolean Implements IRepository.ContainsItem
' ...
End Function
Public Sub CreateOrUpdateItem(item As RepositoryItem, userImportData As String, sourceStream As Stream) Implements IRepository.CreateOrUpdateItem
' ...
End Sub
Sub DeleteItem(itemID As String) Implements IRepository.DeleteItem
' ...
End Sub
Public Function GetAllItems() As IEnumerable(Of RepositoryItem) Implements IRepository.GetAllItems
' ...
End Function
Public Function GetItem(itemID As String) As RepositoryItem Implements IRepository.GetItem
' ...
End Function
Public Sub LoadItem(itemID As String, destinationStream As Stream, cancelToken As CancellationToken) Implements IRepository.LoadItem
' ...
End Sub
Public Function LockItem(id As String) As Boolean Implements IRepository.LockItem
' ...
End Function
Public Sub UnlockItem(id As String) Implements IRepository.UnlockItem
' ...
End Sub
End Class
According to the description in IRepository.ContainsItem this function is called to check if an suitable element exists in the Repository. Therefore you need to ask the database if the requested ID exists:
public class SQLiteFileRepository : IRepository
{
// ...
public bool ContainsItem(string itemID)
{
int result = Convert.ToInt32(_db.CreateCommand(
"SELECT COUNT(*) FROM RepoItems WHERE ItemID = @ItemID")
.SetParameter("ItemID", itemID).ExecuteScalar());
return (result == 1);
}
// ...
}
Public Class SQLiteFileRepository Implements IRepository
'...
Public Function ContainsItem(itemID As String) As Boolean Implements IRepository.ContainsItem
Dim result As Integer = Convert.ToInt32(_db.CreateCommand("SELECT COUNT(*) FROM RepoItems WHERE ItemID = @ItemID").SetParameter("ItemID", itemID).ExecuteScalar())
Return (result = 1)
End Function
' ...
End Class
IRepository.CreateOrUpdateItem
According to the description in IRepository.CreateOrUpdateItem this function is called, if a new element will added to the Repository or an existing one should be updated. However this function is also called, if only the meta data of the element should be updated or the meta data should be added independently of the content:
public class SQLiteFileRepository : IRepository
{
// ...
public void CreateOrUpdateItem(RepositoryItem item, string userImportData, Stream sourceStream)
{
// Convert stream from List & Label to byte array to store it in the DB
// Warning: sourceStream may be null! In that case, only the metadata should be changed in the database.
byte[] fileContent = null;
bool setMetadataOnly;
if (sourceStream != null)
{
using (var memStream = new MemoryStream())
{
sourceStream.CopyTo(memStream);
fileContent = memStream.ToArray();
}
setMetadataOnly = false;
}
else
{
setMetadataOnly = true;
}
// Need to update an existing item or is it a new one?
RepositoryItem itemToInsert;
bool isUpdate = ContainsItem(item.InternalID);
if (isUpdate)
{
// Update an existing Repository Item
itemToInsert = GetItemsFromDb(item.InternalID).First();
itemToInsert.Descriptor = item.Descriptor;
itemToInsert.LastModificationUTC = item.LastModificationUTC;
}
else
{
// Add new Repository Item
itemToInsert = new RepositoryItem(item.InternalID, item.Descriptor, item.Type, item.LastModificationUTC);
}
// Create a suitable SQL query for INSERT / UPDATE and call it with/without the file content.
string sqlQuery;
if (isUpdate) // UPDATE
{
if (setMetadataOnly)
{
sqlQuery = @"UPDATE RepoItems
SET Descriptor = @Descriptor, TimestampUTC = @TimestampUTC
WHERE ItemID = @ItemID";
}
else
{
sqlQuery = @"UPDATE RepoItems
SET Descriptor = @Descriptor, TimestampUTC = @TimestampUTC, FileContent = @FileContent
WHERE ItemID = @ItemID";
}
}
else // INSERT
{
if (setMetadataOnly)
{
sqlQuery = @"INSERT INTO RepoItems (ItemID, Type, Descriptor, TimestampUTC)
VALUES (@ItemID, @Type, @Descriptor, @TimestampUTC)";
}
else
{
sqlQuery = @"INSERT INTO RepoItems (ItemID, Type, Descriptor, TimestampUTC, FileContent)
VALUES (@ItemID, @Type, @Descriptor, @TimestampUTC, @FileContent)";
}
}
_db.CreateCommand(sqlQuery)
.SetParameter("ItemID", itemToInsert.InternalID)
.SetParameter("Type", itemToInsert.Type)
.SetParameter("Descriptor", itemToInsert.Descriptor)
.SetParameter("FileContent", fileContent)
.SetParameter("TimestampUTC", itemToInsert.LastModificationUTC.ToBinary()) // Note that this is always UTC time (convert to local time for the UI)
.ExecuteNonQuery();
}
// ...
}
Public Class SQLiteFileRepository Implements IRepository
' ...
Public Sub CreateOrUpdateItem(item As RepositoryItem, userImportData As String, sourceStream As Stream) Implements IRepository.CreateOrUpdateItem
' Convert stream from List & Label to byte array to store it in the DB
' Warning: sourceStream may be null! In that case, only the metadata should be changed in the database.
Dim fileContent As Byte() = Nothing
Dim setMetadataOnly As Boolean
If sourceStream IsNot Nothing Then
Using memStream = New MemoryStream()
sourceStream.CopyTo(memStream)
fileContent = memStream.ToArray()
End Using
setMetadataOnly = False
Else
setMetadataOnly = True
End If
' Need to update an existing item or is it a new one?
Dim itemToInsert As RepostoryItem
Dim isUpdate As Boolean = ContainsItem(item.InternalID)
If isUpdate Then
' Update an existing Repository Item
itemToInsert = GetItemsFromDb(item.InternalID).First()
itemToInsert.Descriptor = item.Descriptor
itemToInsert.LastModificationUTC = item.LastModificationUTC
Else
' Add new Repository Item
itemToInsert = New RepostoryItem(item.InternalID, item.Descriptor, item.Type, item.LastModificationUTC)
End If
' Create a suitable SQL query for INSERT / UPDATE and call it with/without the file content.
Dim sqlQuery As String
If isUpdate Then
' UPDATE
If setMetadataOnly Then
sqlQuery = "UPDATE RepoItems SET Descriptor = @Descriptor, TimestampUTC = @TimestampUTC WHERE ItemID = @ItemID"
Else
sqlQuery = "UPDATE RepoItems SET Descriptor = @Descriptor, TimestampUTC = @TimestampUTC, FileContent = @FileContent WHERE ItemID = @ItemID"
End If
Else
' INSERT
If setMetadataOnly Then
sqlQuery = "INSERT INTO RepoItems (ItemID, Type, Descriptor, TimestampUTC) VALUES (@ItemID, @Type, @Descriptor, @TimestampUTC)"
Else
sqlQuery = "INSERT INTO RepoItems (ItemID, Type, Descriptor, TimestampUTC, FileContent) VALUES (@ItemID, @Type, @Descriptor, @TimestampUTC, @FileContent)"
End If
End If
' Note that this is always UTC time (convert to local time for the UI)
_db.CreateCommand(sqlQuery) _
.SetParameter("ItemID", itemToInsert.InternalID) _
.SetParameter("Type", itemToInsert.Type) _
.SetParameter("Descriptor", itemToInsert.Descriptor) _
.SetParameter("FileContent", fileContent) _
.SetParameter("TimestampUTC", itemToInsert.LastModificationUTC.ToBinary()) _
.ExecuteNonQuery()
End Sub
' ...
End Class
According to the description in IRepository.DeleteItem this function is called, if an element should be deleted from the Repository. Therefore the related record have to be deleted from the SQLite database:
public class SQLiteFileRepository : IRepository
{
// ...
public void DeleteItem(string itemID)
{
_db.CreateCommand("DELETE FROM RepoItems WHERE ItemID = @ItemID")
.SetParameter("ItemID", itemID)
.ExecuteNonQuery();
}
// ...
}
Public Class SQLiteFileRepository Implements IRepository
' ...
Public Sub DeleteItem(itemID As String) Implements IRepository.DeleteItem
_db.CreateCommand("DELETE FROM RepoItems WHERE ItemID = @ItemID").SetParameter("ItemID", itemID).ExecuteNonQuery()
End Sub
' ...
End Class
This implementation is called to get all existing elements in the Repository (see also IRepository.GetAllItems):
public class SQLiteFileRepository : IRepository
{
// ...
public IEnumerable<RepositoryItem> GetAllItems()
{
List<RepositoryItem> result = new List<RepositoryItem>();
var cmd = _db.CreateCommand("SELECT ItemID, Type, Descriptor, TimestampUTC, LENGTH(FileContent) FROM RepoItems");
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(new RepositoryItem(
/* ItemID */ reader.GetString(0),
/* Descriptor */ reader.GetString(2),
/* Type */ reader.GetString(1),
/* TimestampUTC */ DateTime.FromBinary(reader.GetInt64(3)))
{
IsEmpty = reader.IsDBNull(4) ? true : (reader.GetInt32(4) == 0 ? true : false)
});
}
}
return result;
}
// ...
}
Public Class SQLiteFileRepository Implements IRepository
' ...
Public Function GetAllItems() As IEnumerable(Of RepositoryItem) Implements IRepository.GetAllItems
Dim result As New List(Of RepositoryItem)()
Dim cmd = _db.CreateCommand("SELECT ItemID, Type, Descriptor, TimestampUTC, LENGTH(FileContent) FROM RepoItems")
Using reader = cmd.ExecuteReader()
While reader.Read()
' ItemID
' Descriptor
' Type
' TimestampUTC
result.Add(New RepositoryItem(reader.GetString(0), reader.GetString(2), reader.GetString(1), DateTime.FromBinary(reader.GetInt64(3))) _
With {.IsEmpty = If(reader.IsDBNull(4), True, (If(reader.GetInt32(4) = 0, True, False)))})
End While
End Using
Return result
End Sub
' ...
End Class
To return only one element from the Repository the implementation of IRepository.GetItem is called with the requested ID:
public class SQLiteFileRepository : IRepository
{
// ...
public RepositoryItem GetItem()
{
List<RepositoryItem> result = new List<RepositoryItem>();
var cmd = _db.CreateCommand("SELECT ItemID, Type, Descriptor, TimestampUTC, LENGTH(FileContent) FROM RepoItems WHERE ItemID = @ItemId");
cmd.SetParameter("ItemId", itemId);
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
result.Add(new RepositoryItem(
/* ItemID */ reader.GetString(0),
/* Descriptor */ reader.GetString(2),
/* Type */ reader.GetString(1),
/* TimestampUTC */ DateTime.FromBinary(reader.GetInt64(3)))
{
IsEmpty = reader.IsDBNull(4) ? true : (reader.GetInt32(4) == 0 ? true : false)
});
}
}
return result.FirstOrDefault();
}
// ...
}
Public Class SQLiteFileRepository Implements IRepository
' ...
Public Function GetItem(itemID As String) As RepositoryItem Implements IRepository.GetItem
Dim result As New List(Of RepositoryItem)()
Dim cmd = _db.CreateCommand("SELECT ItemID, Type, Descriptor, TimestampUTC, LENGTH(FileContent) FROM RepoItems WHERE ItemID = @ItemId")
cmd.SetParameter("ItemId", itemId)
Using reader = cmd.ExecuteReader()
While reader.Read()
' ItemID
' Descriptor
' Type
' TimestampUTC
result.Add(New RepositoryItem(reader.GetString(0), reader.GetString(2), reader.GetString(1), DateTime.FromBinary(reader.GetInt64(3))) _
With {.IsEmpty = If(reader.IsDBNull(4), True, (If(reader.GetInt32(4) = 0, True, False)))})
End While
End Using
Return result.FirstOrDefault()
End Sub
' ...
End Class
If the content of an element is really requested and should be loaded from the Repository, for example to open a project file in the designer, the implementation of IRepository.LoadItem is called and we have to return the content of the requested element as stream:
public class SQLiteFileRepository : IRepository
{
// ...
public void LoadItem(string itemID, Stream destinationStream, CancellationToken cancelToken)
{
byte[] content = (byte[])_db.CreateCommand(
"SELECT FileContent FROM RepoItems WHERE ItemID = @ItemID")
.SetParameter("ItemID", itemID).ExecuteScalar();
destinationStream.Write(content, 0, content.Length);
}
// ...
}
Public Class SQLiteFileRepository Implements IRepository
' ...
Public Sub LoadItem(itemID As String, destinationStream As Stream, cancelToken As CancellationToken) Implements IRepository.LoadItem
Dim content As Byte()
content = DirectCast(_db.CreateCommand("SELECT FileContent FROM RepoItems WHERE ItemID = @ItemID").SetParameter("ItemID", itemID).ExecuteScalar(), Byte())
destinationStream.Write(content, 0, content.Length)
End Sub
' ...
End Class
If the requirement exists to editing an element exclusively - for example if a project is opening in the designer - an exclusively access with the help of IRepository.LockItem could be implemented to lock the element:
public class SQLiteFileRepository : IRepository
{
// ...
public bool LockItem(string id)
{
// IMPORTANT: Always implement a fallback to release the locks (e.g. timeout).
// Especially when used in a network application, UnlockItem() might not get called due to network problems.
// Return true, if the lock was acquired or if no locking is implemented.
// Return false, if the item is locked by an other user. The designer will show an error message and open the item in read-only mode.
return true;
}
// ...
}
Public Class SQLiteFileRepository Implements IRepository
' ...
Public Function LockItem(id As String) As Boolean Implements IRepository.LockItem
' IMPORTANT: Always implement a fallback to release the locks (e.g. timeout).
' Especially when used in a network application, UnlockItem() might not get called due to network problems.
' Return True, if the lock was acquired or if no locking is implemented.
' Return False, if the item is locked by an other user. The designer will show an error message and open the item in read-only mode.
Return True
End Function
' ...
End Class
This is required to unlock an element in the Repository if it was locked with the call of IRepository.LockItem before:
public class SQLiteFileRepository : IRepository
{
// ...
public void UnlockItem(string id)
{
// ...
}
// ...
}
Public Class SQLiteFileRepository Implements IRepository
' ...
Public Sub UnlockItem(id As String) Implements IRepository.UnlockItem
' ...
End Sub
' ...
End Class
Helper function to update the meta data of an Repository element
To be able to update meta data of an element in the Repository like the display name in the designer of a project file, it requires a little helper function which writes this adaptations into the SQLite database:
public class SQLiteFileRepository : IRepository
{
// ...
public void SetItemMetadata(string itemID, string descriptor)
{
_db.CreateCommand(@"
UPDATE RepoItems
SET Descriptor = @Descriptor
WHERE ItemID = @ItemID")
.SetParameter("Descriptor", descriptor)
.SetParameter("ItemID", itemID)
.ExecuteNonQuery();
}
// ...
}
Public Class SQLiteFileRepository Implements IRepository
' ...
Public Sub SetItemMetadata(itemID As String, descriptor As String, showReportInToolbar As Boolean, originalFileName As String)
_db.CreateCommand("UPDATE RepoItems SET Descriptor = @Descriptor WHERE ItemID = @ItemID") _
.SetParameter("Descriptor", descriptor) _
.SetParameter("ItemID", itemID).ExecuteNonQuery()
End Sub
' ...
End Class
From now all concerning List & Label files are managed in a SQLite database. How to work with this Repository is shown in "Step 3: Usage of the self-created IRepository implementation".
Step 3: Usage of the self-created IRepository implementation
Helper class for the simple access to the Repository
With the help of this class the access to the self implemented Repository is simplified and it is also the base for the following steps:
// Helper class
public class RepositoryHelper
{
// Implemented interface from Step 2
private static SQLiteFileRepository _fileRepository;
public static SQLiteFileRepository GetCurrentRepository()
{
if (_fileRepository == null)
{
_fileRepository = new SQLiteFileRepository(Global.RepositoryDatabaseFile);
}
return _fileRepository;
}
// Sets a display name for a repository item.
// Note that this name is only used in the dialogs of the designer!
// The repository item is still only identified by it's ID.
public static void SetRepositoryItemProperties(string itemId, string name)
{
RepostoryItem modifiedItem = GetCurrentRepository().GetItem(itemId);
// Get the (encoded) descriptor of this repository item (contains metadata like the display name).
string descriptorString = modifiedItem.Descriptor;
// Decode the string and set the entered display name for the UI.
var descriptor = RepositoryItemDescriptor.LoadFromDescriptorString(descriptorString);
descriptor.SetUIName(0, name); // 0 = Standardsprache
descriptorString = descriptor.SerializeToString();
// Save the updated descriptor in our repository.
GetCurrentRepository().SetItemMetadata(itemId, descriptorString);
}
}
' Helper class
Public Class RepositoryHelper
' Implemented interface from Step 2
Private Shared _fileRepository As SQLiteFileRepository
Public Shared Function GetCurrentRepository() As SQLiteFileRepository
If _fileRepository Is Nothing Then
_fileRepository = New SQLiteFileRepository([Global].RepositoryDatabaseFile)
End If
Return _fileRepository
End Function
' Sets a display name for a repository item.
' Note that this name is only used in the dialogs of the designer!
' The repository item is still only identified by it's ID.
Public Shared Sub SetRepositoryItemProperties(itemId As String, name As String)
Dim modifiedItem As RepostoryItem = GetCurrentRepository().GetItem(itemId)
' Get the (encoded) descriptor of this repository item (contains metadata like the display name).
Dim descriptorString As String = modifiedItem.Descriptor
' Decode the string and set the entered display name for the UI.
Dim descriptor = RepositoryItemDescriptor.LoadFromDescriptorString(descriptorString)
descriptor.SetUIName(0, name) ' 0 = default language
descriptorString = descriptor.SerializeToString()
' Save the updated descriptor in our repository.
GetCurrentRepository().SetItemMetadata(itemId, descriptorString)
End Sub
End Class
Add/Import of existing files from file system into the Repository
In order to be able to import existing files like project files, drawings, shapefiles etc. you can use the supplied helper class RepositoryImportUtil for that:
// Executes a suitable import call for the file type and returns the ID(s) of the created repository item(s).
private void AddFileToRepository(RepositoryItemType fileType, string file1, string file2)
{
string createdItemId1 = null;
string createdItemId2 = null;
// The RepositoryImportUtil class helps to create new items & import existing files.
using (RepositoryImportUtil util = new RepositoryImportUtil(RepositoryHelper.GetCurrentRepository()))
{
using (ListLabel LL = new ListLabel())
{
// Consider the possibility to pass a custom information to the CreateOrUpdate() method (in SQLiteFileRepository),
// which is internally called by the import and where this data will be available in the "userImportData" parameter.
string userImportData = "Some custom information for your repository";
if (RepositoryItemType.IsProjectType(fileType))
{
createdItemId1 = util.ImportProjectFile(LL, file1, userImportData /* , printerConfigFile, sketchImageFile */);
}
else if (fileType == RepositoryItemType.Image)
{
createdItemId1 = util.ImportImageFile(LL, file1, userImportData);
}
else if (fileType == RepositoryItemType.PDF)
{
createdItemId1 = util.ImportPdfFile(LL, file1, userImportData);
}
else if (fileType == RepositoryItemType.ProjectReverseSide)
{
createdItemId1 = util.ImportReverseSideFile(LL, file1, userImportData);
}
else if (fileType == RepositoryItemType.ProjectTableOfContents)
{
createdItemId1 = util.ImportTableOfContentsFile(LL, file1, userImportData);
}
else if (fileType == RepositoryItemType.ProjectIndex)
{
createdItemId1 = util.ImportIndexFile(LL, file1, userImportData);
}
else if (fileType == RepositoryItemType.Shapefile)
{
// ImportShapeFile() returns two IDs (for shapefile and database file)
var createdShapeFileItems = util.ImportShapefile(LL, file1, file2, userImportData);
createdItemId1 = createdShapeFileItems.Item1;
createdItemId2 = createdShapeFileItems.Item2;
}
// Use the original file name (without file extension) as the UI display name of the repository item and add it as report to the toolbar if requested.
string displayName1 = file1.FileName;
if (fileType != RepositoryItemType.Shapefile) // Keep file extension only for shapefiles (two files with the same name)
displayName1 = Path.GetFileNameWithoutExtension(displayName1);
RepositoryHelper.SetRepositoryItemProperties(createdItemId1, displayName1);
if (createdItemId2 != null)
RepositoryHelper.SetRepositoryItemProperties(createdItemId2, Path.GetFileNameWithoutExtension(file2));
}
}
}
' Executes a suitable import call for the file type and returns the ID(s) of the created repository item(s).
Private Sub AddFileToRepository(fileType As RepositoryItemType, file1 As String, file2 As String)
Dim createdItemId1 As String = Nothing
Dim createdItemId2 As String = Nothing
' The RepositoryImportUtil class helps to create new items & import existing files.
Using util As New RepositoryImportUtil(RepositoryHelper.GetCurrentRepository())
Using LL As New ListLabel()
' Consider the possibility to pass a custom information to the CreateOrUpdate() method (in SQLiteFileRepository),
' which is internally called by the import and where this data will be available in the "userImportData" parameter.
Dim userImportData As String = "Some custom information for your repository"
If RepositoryItemType.IsProjectType(fileType) Then
createdItemId1 = util.ImportProjectFile(LL, file1, userImportData)
ElseIf fileType.Value = RepositoryItemType.Image.Value Then
createdItemId1 = util.ImportImageFile(LL, file1, userImportData)
ElseIf fileType.Value = RepositoryItemType.PDF.Value Then
createdItemId1 = util.ImportPdfFile(LL, file1, userImportData)
ElseIf fileType.Value = RepositoryItemType.ProjectReverseSide.Value Then
createdItemId1 = util.ImportReverseSideFile(LL, file1, userImportData)
ElseIf fileType.Value = RepositoryItemType.ProjectTableOfContents.Value Then
createdItemId1 = util.ImportTableOfContentsFile(LL, file1, userImportData)
ElseIf fileType.Value = RepositoryItemType.ProjectIndex.Value Then
createdItemId1 = util.ImportIndexFile(LL, file1, userImportData)
ElseIf fileType.Value = RepositoryItemType.Shapefile.Value Then
' ImportShapeFile() returns two IDs (for shapefile and database file)
Dim createdShapeFileItems = util.ImportShapefile(LL, file1, file2, userImportData)
createdItemId1 = createdShapeFileItems.Item1
createdItemId2 = createdShapeFileItems.Item2
End If
' Use the original file name (without file extension) as the UI display name of the repository item and add it as report to the toolbar if requested.
Dim displayName1 As String = FileUploadItem.FileName
If fileType.Value <> RepositoryItemType.Shapefile.Value Then
' Keep file extension only for shapefiles (two files with the same name)
displayName1 = Path.GetFileNameWithoutExtension(file1)
End If
RepositoryHelper.SetRepositoryItemProperties(createdItemId1, displayName1)
If createdItemId2 IsNot Nothing Then
RepositoryHelper.SetRepositoryItemProperties(createdItemId2, Path.GetFileNameWithoutExtension(file2))
End If
End Using
End Using
End Sub
Creating new elements (new project files) into the Repository
If a new project file should be created and editing in the designer you also can use the helper class RepositoryImportUtil and its suitable function CreateNewProject:
private void CreateNewRepositoryItem(LlProject projectType, string name)
{
// The RepositoryImportUtil class helps to create new items & import existing files.
string createdItemID;
using (RepositoryImportUtil util = new RepositoryImportUtil(RepositoryHelper.GetCurrentRepository()))
{
createdItemID = util.CreateNewProject(projectType, name);
}
// If we don't want to see the ID of the repository item, we need to set a name to display in the UI.
RepositoryHelper.SetRepositoryItemProperties(createdItemID, name);
}
private Sub CreateNewRepositoryItem(projectType As LlProject, name As String)
' The RepositoryImportUtil class helps to create new items & import existing files.
Dim createdItemID As String
Using util As New RepositoryImportUtil(RepositoryHelper.GetCurrentRepository())
createdItemID = util.CreateNewProject(projectType, name)
End Using
' If we don't want to see the ID of the repository item, we need to set a name to display in the UI.
RepositoryHelper.SetRepositoryItemProperties(createdItemID, name)
End Sub
Delete elements from the Repository
To delete elements from the Repository based on their ID you can directly call the provided implementation of IRepository.DeleteItem:
private void DeleteRepositoryItem(String itemID)
{
RepositoryHelper.GetCurrentRepository().DeleteItem(itemID);
}
private Sub DeleteRepositoryItem(itemID As String)
RepositoryHelper.GetCurrentRepository().DeleteItem(itemID)
End Sub
The supplied programming samples show the implementation of the IRepository-Interface based on a SQLite database and its following usage in detail.